package com.teatime.client.view;

import com.teatime.client.TLog;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.ImageView;

public class DragGridView extends GridView {
    private int dragPosition;
    private int dropPosition;
    private int dragPointX;
    private int dragPointY;
    private int dragOffsetX;
    private int dragOffsetY;
    private int overPosition;
    private ImageView dragImageView;
    private WindowManager windowManager;
    private WindowManager.LayoutParams windowParams;
    private OnItemDragListener itemDragListener;
    private boolean mHasSort;
    
    public DragGridView(Context context) {
        super(context);
        overPosition = AdapterView.INVALID_POSITION;
        itemDragListener = null;
        mHasSort = false;
    }
    
    public DragGridView(Context context, AttributeSet attrs) {
        super(context, attrs);
        overPosition = AdapterView.INVALID_POSITION;
        mHasSort = false;
    }
    
    public void setOnItemDragListener(OnItemDragListener listener) {
    	itemDragListener = listener;
    }
    
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        TLog.v("onInterceptTouchEvent" + super.onInterceptTouchEvent(ev));
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            int x = (int)ev.getX();
            int y = (int)ev.getY();
            dragPosition = dropPosition = pointToPosition(x, y);
            //TLog.d("dragPosition=" + dragPosition);
            if (dragPosition == AdapterView.INVALID_POSITION) {
                return super.onInterceptTouchEvent(ev);
            }
            //TLog.v("getFirstPosition" + getFirstVisiblePosition());
            View itemView = (View)getChildAt(dragPosition - getFirstVisiblePosition());
            
            dragPointX = x - itemView.getLeft();
            dragPointY = y - itemView.getTop();
            
            dragOffsetX = (int)(ev.getRawX() - x);
            dragOffsetY = (int)(ev.getRawY() - y);
            
            //TLog.d("dragPointX=" + dragPointX + ",dragPointY=" + dragPointY + ",dragOffsetX=" + dragOffsetX
            //   + ",dragOffsetY=" + dragOffsetY);
            
            //itemView.destroyDrawingCache();
            //itemView.setDrawingCacheEnabled(true);
            ImageGridAdapter adapter = (ImageGridAdapter)this.getAdapter();
            Bitmap bm = adapter.getImage(dragPosition);
            adapter.setMoving(dragPosition);
            adapter.notifyDataSetChanged();
            //Bitmap bm = Bitmap.createBitmap(itemView.getDrawingCache());
            
            startDrag(bm, x, y);
            return false;
        }
        return super.onInterceptTouchEvent(ev);
    }
    
    private void startDrag(Bitmap bm, int x, int y) {
    	TLog.v("startDrag");
    	if (itemDragListener != null) {
    		TLog.v("startDrag itemDragListener");
    		itemDragListener.onDragStart(this, dragPosition);
    	}
    	
        stopDrag();
        windowParams = new WindowManager.LayoutParams();
        //TLog.v("X:" + x + " dragPointX:" + dragPointX + " dragOffsetX:" + dragOffsetX);
        windowParams.gravity = Gravity.TOP | Gravity.LEFT;
        windowParams.x = x - dragPointX + dragOffsetX;
        windowParams.y = y - dragPointY + dragOffsetY;

        windowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
        windowParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
        windowParams.flags =
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
        
        windowParams.format = PixelFormat.TRANSLUCENT;
        windowParams.windowAnimations = 0;
        windowParams.width = 100;
        windowParams.height = 100;
        ImageView iv = new ImageView(getContext());
        //iv.setLayoutParams(new GridView.LayoutParams(100, 100));
        iv.setScaleType(ImageView.ScaleType.CENTER_CROP);
        iv.setImageBitmap(bm);
        windowManager = (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);//"window" 
        windowManager.addView(iv, windowParams);
        dragImageView = iv;
        
    }
    
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (dragImageView != null && dragPosition != AdapterView.INVALID_POSITION) {
            
            switch (ev.getAction()) {
                case MotionEvent.ACTION_UP:
                    int upX = (int)ev.getX();   
                    int upY = (int)ev.getY();
                    if (itemDragListener != null) {
                		 itemDragListener.onDragStop(this, dragPosition, upX, upY);
                	}
                    stopDrag(); 
                    onDrop(upX,upY); 
                    ImageGridAdapter adapter = (ImageGridAdapter)this.getAdapter();
                    adapter.notifyDataSetChanged();
                    break;
           
                case MotionEvent.ACTION_MOVE:
                    int moveX = (int)ev.getX();                 
                    int moveY = (int)ev.getY();
                    if (itemDragListener != null) {
                    	itemDragListener.onDrag(this, dragPosition, moveX, moveY);
                    }
                    //TLog.v("ACTION_MOVE x" + moveX + "ev.getRawx=" + ev.getRawX());
                    onDrag(moveX,moveY);
                    break;
           
            }
        }
        return super.onTouchEvent(ev);
    }
    
/*    private boolean isOverlap(View view1, View view2) {
    	Rect rect1 = new Rect(view1.getLeft(), view1.getTop(),
    			view1.getRight(), view1.getBottom()),
    		 rect2 = new Rect(view2.getLeft(), view2.getTop(),
    	    			view2.getRight(), view2.getBottom());
    	return rect1.intersect(rect2);
    }
    */
    private void onDrag(int x, int y) {
        if (dragImageView != null) {
            //windowParams.alpha = 1.0f;
            
            // x-dragPointx = getLeft();
            // y-dragPonitY = getTop();
            windowParams.x = x - dragPointX + dragOffsetX;
            windowParams.y = y - dragPointY + dragOffsetY;
            windowManager.updateViewLayout(dragImageView, windowParams);
            
            int op = pointToPosition(x, y);
            ImageGridAdapter adapter = (ImageGridAdapter)getAdapter();
            if (op != AdapterView.INVALID_POSITION
            	&& op != dragPosition) {
            	if (op != overPosition) {
            		overPosition = op;
            		adapter.preExchange(op);
            		adapter.notifyDataSetChanged();
            	}
            }
            else {
            	if (op == AdapterView.INVALID_POSITION
            		&& overPosition != AdapterView.INVALID_POSITION) {
            		overPosition = AdapterView.INVALID_POSITION;
           			adapter.noPreExchange();
           			adapter.notifyDataSetChanged();
            	}
            }
            
        }
    }
    
    private void onDrop(int x, int y) {
    	boolean exchange = false;
        int tempPosition = pointToPosition(x, y);
        if (tempPosition != AdapterView.INVALID_POSITION) {
            dropPosition = tempPosition;
            if (dropPosition != dragPosition) {
            	exchange = true;
            }
        }
        
        if (exchange) {
        	ImageGridAdapter adapter = (ImageGridAdapter)this.getAdapter();
            adapter.exchange(dragPosition, dropPosition);
            adapter.notifyDataSetChanged();
            mHasSort = true;
            /*
             * ViewGroup itemView1 = (ViewGroup)getChildAt(dragPosition -
             * getFirstVisiblePosition()); ViewGroup itemView2 =
             * (ViewGroup)getChildAt(dropPosition - getFirstVisiblePosition());
             * itemView1.destroyDrawingCache(); itemView2.destroyDrawingCache();
             */
        }
        else {
        	ImageGridAdapter adapter = (ImageGridAdapter)this.getAdapter();
        	adapter.restore();
        	adapter.notifyDataSetChanged();
        }
        
    }
    
    private void stopDrag() {
    	
        if (dragImageView != null) {
            windowManager.removeView(dragImageView);
            dragImageView = null;
        }
        
    }
    
    public boolean hasSort() {
    	return mHasSort;
    }
    
    public interface OnItemDragListener {  
        void onDragStart(GridView grid,
        		int dragPosition);
        void onDrag(GridView grid,
        		int dragPosition, int moveX, int moveY);
        void onDragStop(GridView grid,
        		int dragPosition, int stopX, int stopY);
    }
    
}